
package com.lzx.iteam.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.*;
import android.widget.AbsListView.OnScrollListener;
import com.lzx.iteam.CloudDialerActivity;
import com.lzx.iteam.R;
import com.lzx.iteam.adapter.AmazingAdapter;
import com.lzx.iteam.adapter.CloudContactAdapter;
import com.lzx.iteam.adapter.ContactEntryAdapter;

/**
 * A ListView that maintains a header pinned at the top of the list. The pinned
 * header can be pushed up and dissolved as needed. It also supports pagination
 * by setting a custom view as the loading indicator.
 */
public class AmazingListView extends ListView implements AmazingAdapter.HasMorePagesListener, OnScrollListener {
    public static final String TAG = AmazingListView.class.getSimpleName();

    View listFooter;

    boolean footerViewAttached = false;

    private View mHeaderView;
    private View mFooterView;//add by lk for pull more
    private boolean mIsLoading;// 判断是否正在加载
    private boolean mLoadEnable = true;// 开启或者关闭加载更多功能
    private OnLoadListener mOnLoadListener;

    private boolean mHeaderViewVisible;
    
    private boolean misVisible = true;

    private int mHeaderViewWidth;

    private int mHeaderViewHeight;

    private ListAdapter mAdapter;

    private int headerViewColor;

    private int headerViewTextColor;

    private final static int RELEASE_To_REFRESH = 0;

    private final static int PULL_To_REFRESH = 1;

    private final static int REFRESHING = 2;

    private final static int DONE = 3;

    private final static int LOADING = 4;

    // 实际的padding的距离与界面上偏移距离的比例
    private final static int RATIO = 3;

    private LayoutInflater inflater;

    private LinearLayout headView;

    private TextView tipsTextview;

    private ImageView arrowImageView;

    private boolean isRecored;

    private int headContentWidth;

    private int headContentHeight;

    private int startY;

    public int firstItemIndex;

    private int state;

    private boolean isBack;

    private OnRefreshListener refreshListener;

    private boolean isRefreshable;

    private RotateAnimation animation;

    private RotateAnimation reverseAnimation;

    private int mScrollState;

    private CloudDialerActivity mActivity;
    
    private Context mContext;

    public AmazingListView(Context context) {
        super(context);
        if(isInEditMode()){
            return;
        }
        init(context);
        mContext = context;
    }

    public AmazingListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(isInEditMode()){
            return;
        }
        init(context);
        mContext = context;
    }

    public AmazingListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if(isInEditMode()){
            return;
        }
        init(context);
        mContext = context;
    }

    private void init(Context context) {
//        mActivity = (CloudDialerActivity)(context);
        setCacheColorHint(context.getResources().getColor(R.color.transparent));
        inflater = LayoutInflater.from(context);

        headView = (LinearLayout) inflater.inflate(R.layout.head, null);
        mFooterView = inflater.inflate(R.layout.amazing_list_footer,null);
        // 剪头图标
        arrowImageView = (ImageView) headView.findViewById(R.id.head_arrowImageView);
        arrowImageView.setMinimumWidth(70);
        arrowImageView.setMinimumHeight(50);
        tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
        measureView(headView);
        headContentHeight = headView.getMeasuredHeight();
        headContentWidth = headView.getMeasuredWidth();

        headView.setPadding(0, -1 * headContentHeight, 0, 0);
        headView.invalidate();

        Log.v("size", "width:" + headContentWidth + " height:" + headContentHeight);

        addHeaderView(headView, null, false);
//        addFooterView(mFooterView);//add by lk for pull more
        // 转动动画
        animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        animation.setInterpolator(new LinearInterpolator());
        animation.setDuration(250);
        animation.setFillAfter(true); // 保留在终止位

        reverseAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        reverseAnimation.setInterpolator(new LinearInterpolator());
        reverseAnimation.setDuration(200);
        reverseAnimation.setFillAfter(true);

        state = DONE;
        isRefreshable = false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (isRefreshable) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (firstItemIndex == 0 && !isRecored) {
                        isRecored = true;
                        startY = (int) event.getY();
                        Log.v(TAG, "在down时候记录当前位置‘");
                        misVisible = false;
                    }
                    
                    break;

                case MotionEvent.ACTION_UP:
                    misVisible = true;
                    if (state != REFRESHING && state != LOADING) {
                        if (state == DONE) {
                            // 什么都不做
                        }
                        if (state == PULL_To_REFRESH) {
                            state = DONE;
                            changeHeaderViewByState();

                            Log.v(TAG, "由下拉刷新状态，到done状态");
                        }
                        if (state == RELEASE_To_REFRESH) {
                            state = REFRESHING;
                            changeHeaderViewByState();
                            onRefresh();

                            Log.v(TAG, "由松开刷新状态，到done状态");
                        }
                    }

                    isRecored = false;
                    isBack = false;

                    break;

                case MotionEvent.ACTION_MOVE:
                    int tempY = (int) event.getY();

                    // 当前第一个item是0位置才能触发操作
                    if (!isRecored && firstItemIndex == 0) {
                        Log.v(TAG, "在move时候记录下位置");
                        isRecored = true;
                        startY = tempY;
                        mHeaderViewVisible = false;
                        misVisible = false;
                    }

                    if (state != REFRESHING && isRecored && state != LOADING) {

                        // 保证在设置padding的过程中，当前的位置一直是在head，否则如果当列表超出屏幕的话，当在上推的时候，列表会同时进行滚动

                        // 可以松手去刷新了
                        if (state == RELEASE_To_REFRESH) {

                            setSelection(0);

                            // 往上推了，推到了屏幕足够掩盖head的程度，但是还没有推到全部掩盖的地步
                            if (((tempY - startY) / RATIO < headContentHeight)
                                    && (tempY - startY) > 0) {
                                state = PULL_To_REFRESH;
                                changeHeaderViewByState();

                                Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");
                            }
                            // 一下子推到顶了
                            else if (tempY - startY <= 0) {
                                state = DONE;
                                changeHeaderViewByState();

                                Log.v(TAG, "由松开刷新状态转变到done状态");
                            }
                            // 往下拉了，或者还没有上推到屏幕顶部掩盖head的地步
                            else {
                                // 不用进行特别的操作，只用更新paddingTop的值就行了
                            }
                        }
                        // 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
                        if (state == PULL_To_REFRESH) {

                            setSelection(0);

                            // 下拉到可以进入RELEASE_TO_REFRESH的状态
                            if ((tempY - startY) / RATIO >= headContentHeight) {
                                state = RELEASE_To_REFRESH;
                                isBack = true;
                                changeHeaderViewByState();

                                Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新");
                            }
                            // 上推到顶了
                            else if (tempY - startY <= 0) {
                                state = DONE;
                                changeHeaderViewByState();

                                Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态");
                            }
                        }

                        // done状态下
                        if (state == DONE) {
                            if (tempY - startY > 0) {
                                state = PULL_To_REFRESH;
                                changeHeaderViewByState();
                            }
                        }

                        // 更新headView的size
                        if (state == PULL_To_REFRESH) {
                            headView.setPadding(0, -1 * headContentHeight + (tempY - startY)
                                    / RATIO, 0, 0);

                        }

                        // 更新headView的paddingTop
                        if (state == RELEASE_To_REFRESH) {
                            headView.setPadding(0, (tempY - startY) / RATIO - headContentHeight, 0,
                                    0);
                        }

                    }

                    break;
            }
        }

        return super.onTouchEvent(event);
    }

    /**
     *   当状态改变时候，调用该方法，以更新界面
     */

    private void changeHeaderViewByState() {
        switch (state) {
            case RELEASE_To_REFRESH:
                // 松开刷新
                arrowImageView.setVisibility(View.VISIBLE);
                tipsTextview.setVisibility(View.VISIBLE);

                arrowImageView.clearAnimation();
                arrowImageView.startAnimation(animation);

                tipsTextview.setText("松开立即刷新");

                Log.v(TAG, "当前状态，松开刷新");
                break;
            case PULL_To_REFRESH:
                // 下拉刷新
                tipsTextview.setVisibility(View.VISIBLE);
                arrowImageView.clearAnimation();
                arrowImageView.setVisibility(View.VISIBLE);
                // 是由RELEASE_To_REFRESH状态转变来的
                // 没有松开刷新而是慢慢返回
                if (isBack) {
                    isBack = false;
                    arrowImageView.clearAnimation();
                    arrowImageView.startAnimation(reverseAnimation);

                    tipsTextview.setText("下拉可以刷新");
                } else {
                    tipsTextview.setText("下拉可以刷新");
                }
                Log.v(TAG, "当前状态，下拉刷新");
                break;

            case REFRESHING:
                // 正在刷新

                headView.setPadding(0, 0, 0, 0);
                arrowImageView.clearAnimation();
                arrowImageView.setVisibility(View.GONE);
                tipsTextview.setText("正在刷新...");
                Log.v(TAG, "当前状态,正在刷新...");
                break;
            case DONE:
                headView.setPadding(0, -1 * headContentHeight, 0, 0);
                arrowImageView.clearAnimation();
                arrowImageView.setImageResource(R.drawable.arrow);
                tipsTextview.setText("下拉刷新");

                Log.v(TAG, "当前状态，done");
                break;
        }
    }

    public void setonRefreshListener(OnRefreshListener refreshListener) {
        this.refreshListener = refreshListener;
        isRefreshable = true;
    }
    
    public void setCanRefreshable(boolean freshable){
        isRefreshable = freshable;
    }

    public interface OnRefreshListener {
        public void onRefresh();
    }

    public void onRefreshComplete() {
        state = DONE;
        changeHeaderViewByState();
    }

    public void refreshStart() {
        state = REFRESHING;
        changeHeaderViewByState();
        if (refreshListener != null) {
            refreshListener.onRefresh();
        }
    }

    private void onRefresh() {

        if (refreshListener != null) {
            refreshListener.onRefresh();
        }
    }

    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    public void setHeaderViewColorAndTextColor(int color, int tvColor) {
        this.headerViewColor = color;
        this.headerViewTextColor = tvColor;
        requestLayout();
    }

    public void setPinnedHeaderView(View view) {

        mHeaderView = view;
        mHeaderView.setBackgroundColor(headerViewColor);
        mHeaderView.setVisibility(View.GONE);
        TextView tv = (TextView) mHeaderView.findViewById(R.id.header);
        tv.setTextColor(headerViewTextColor);
        // Disable vertical fading when the pinned header is present
        // change ListView to allow separate measures for top and bottom
        // fading edge;
        // in this particular case we would like to disable the top, but not the
        // bottom edge.
        if (mHeaderView != null) {
            setFadingEdgeLength(0);
        }
        requestLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mHeaderView != null) {
            measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);
            mHeaderViewWidth = mHeaderView.getMeasuredWidth();
            mHeaderViewHeight = mHeaderView.getMeasuredHeight();
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (mHeaderView != null) {
            mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
            configureHeaderView(getFirstVisiblePosition());
        }
    }

    // public static final int SHADOW_ORIEN_NONE = 0;
    // public static final int SHADOW_ORIEN_LEFT_RIGHT = 1;
    // public static final int SHADOW_ORIEN_RIGHT_LEFT = 2;
    // public static final int SHADOW_ORIEN_BOTTOM_TOP = 3;
    // private int mShadowOrien = SHADOW_ORIEN_NONE;
    //
    // public void setShadowOrien(int orien) {
    // mShadowOrien = orien;
    // invalidate();
    // }
    //
    // @Override
    // protected void onDraw(Canvas canvas) {
    // if (mShadowOrien != SHADOW_ORIEN_NONE) {
    // GradientDrawable.Orientation ori;
    // switch (mShadowOrien) {
    // case SHADOW_ORIEN_LEFT_RIGHT:
    // ori = GradientDrawable.Orientation.LEFT_RIGHT;
    // break;
    // case SHADOW_ORIEN_BOTTOM_TOP:
    // ori = GradientDrawable.Orientation.BOTTOM_TOP;
    // break;
    // default:
    // ori = GradientDrawable.Orientation.RIGHT_LEFT;
    // break;
    // }
    //
    // GradientDrawable rightShadow = new GradientDrawable(ori, new int[] {
    // Color.argb(100, 0, 0, 0), Color.argb(80, 0, 0, 0), Color.argb(10, 0, 0,
    // 0),
    // Color.argb(0, 0, 0, 0)
    // });
    // rightShadow.setGradientType(GradientDrawable.LINEAR_GRADIENT);
    // rightShadow.draw(canvas);
    // }
    //
    // super.onDraw(canvas);
    // }



    /**
     * 设定Section Header的位置，背景色(Fade off), 带部分动画效果实现
     * @param position
     */

    public void configureHeaderView(int position) {
//        if (mHeaderView == null) {
//            return;
//        }
//
//        // int state = adapter.getPinnedHeaderState(position);
//        int state = 0;
//        if (mAdapter instanceof CallLogAdapter) {
//            state = ((CallLogAdapter) mAdapter).getPinnedHeaderState(position);
//        } else if (mAdapter instanceof ContactEntryAdapter) {
//            state = ((ContactEntryAdapter) mAdapter).getPinnedHeaderState(position);
//        } else if (mAdapter instanceof CloudContactAdapter) {
//            state = ((CloudContactAdapter) mAdapter).getPinnedHeaderState(position);
//        }
//
//        switch (state) {
//            case AmazingAdapter.PINNED_HEADER_GONE: {
//                mHeaderViewVisible = false;
//                break;
//            }
//
//            case AmazingAdapter.PINNED_HEADER_VISIBLE: {
//                // adapter.configurePinnedHeader(mHeaderView, position, 255);
//                if (mAdapter instanceof CallLogAdapter) {
//                    ((CallLogAdapter) mAdapter).configurePinnedHeader(mHeaderView, position, 255);
//                } else if (mAdapter instanceof ContactEntryAdapter) {
//                    ((ContactEntryAdapter) mAdapter).configurePinnedHeader(mHeaderView, position,
//                            255);
//                } else if (mAdapter instanceof CloudContactAdapter) {
//                    ((CloudContactAdapter) mAdapter).configurePinnedHeader(mHeaderView, position,
//                            255);
//                }
//
//                if (mHeaderView.getTop() != 0) {
//                    mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
//                }
//                mHeaderViewVisible = true;
//                break;
//            }
//
//            case AmazingAdapter.PINNED_HEADER_PUSHED_UP: {
//                View firstView = getChildAt(0);
//                if (firstView != null) {
//                    int bottom = firstView.getBottom();
//                    int headerHeight = mHeaderView.getHeight();
//                    int y;
//                    // int alpha;
//                    if (bottom < headerHeight) {
//                        y = (bottom - headerHeight);
//                        // alpha = 255 * (headerHeight + y) / headerHeight;
//                    } else {
//                        y = 0;
//                        // alpha = 255;
//                    }
//                    // adapter.configurePinnedHeader(mHeaderView, position,
//                    // alpha);
//                    if (mAdapter instanceof CallLogAdapter) {
//                        ((CallLogAdapter) mAdapter).configurePinnedHeader(mHeaderView, position,
//                                255);
//                    } else if (mAdapter instanceof ContactEntryAdapter) {
//                        ((ContactEntryAdapter) mAdapter).configurePinnedHeader(mHeaderView,
//                                position, 255);
//                    } else if (mAdapter instanceof CloudContactAdapter) {
//                        ((CloudContactAdapter) mAdapter).configurePinnedHeader(mHeaderView,
//                                position, 255);
//                    }
//
//                    if (mHeaderView.getTop() != y) {
//                        mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);
//                    }
//                    mHeaderViewVisible = true;
//                }
//                break;
//            }
//        }
//
//        mHeaderView.setBackgroundColor(headerViewColor);
//        TextView tv = (TextView) mHeaderView.findViewById(R.id.header);
//        tv.setTextColor(headerViewTextColor);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if (mHeaderViewVisible && misVisible) {
            drawChild(canvas, mHeaderView, getDrawingTime());
        }
    }

    public void setLoadingView(View listFooter) {
        this.listFooter = listFooter;
    }

    public View getLoadingView() {
        return listFooter;
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
    	super.setAdapter(adapter);
   	/*
        setOnScrollListener(this);
        this.mAdapter = adapter;

        if (mAdapter instanceof ContactEntryAdapter) {
            // ((ContactItemListAdapter) adapter).setHasMorePagesListener(this);
            this.setOnScrollListener((ContactEntryAdapter) adapter);
            mLoadEnable = false;
            if(mFooterView != null){
                mFooterView.setVisibility(GONE);
            }
        }else if(mAdapter instanceof CloudContactAdapter){
            mLoadEnable = true;
        }
//        else if (mAdapter instanceof CallLogAdapter) {
//            this.setOnScrollListener((CallLogAdapter) adapter);
//        }

*/
        //View dummy = new View(getContext());
        //super.setAdapter(adapter);
        //super.removeFooterView(dummy);
        
        
    }

    @Override
    public ListAdapter getAdapter() {
        return mAdapter;
    }

    @Override
    public void noMorePages() {
        if (listFooter != null) {
            this.removeFooterView(listFooter);
        }
        footerViewAttached = false;
    }

    @Override
    public void mayHaveMorePages() {
        if (!footerViewAttached && listFooter != null) {
            this.addFooterView(listFooter);
            footerViewAttached = true;
        }
    }

    public boolean isLoadingViewVisible() {
        return footerViewAttached;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount) {
        firstItemIndex = firstVisibleItem;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.mScrollState = scrollState;
        isNeedLoadMore(view,scrollState);
    }

    private void isNeedLoadMore(AbsListView view ,int scrollState){
        if (!mLoadEnable) {
            return;
        }
        try {
            if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
                    && !mIsLoading
                    && view.getLastVisiblePosition() == view
                    .getPositionForView(mFooterView) && !mIsLoading) {
                mFooterView.setVisibility(VISIBLE);
                loadMore();
                mIsLoading = true;
            }
        } catch (Exception e) {
        }
    }

    private void loadMore(){
        if (mOnLoadListener != null) {
            mOnLoadListener.onLoad();
        }
    }

    // 用于加载更多结束后的回调
    public void onLoadComplete() {
        mIsLoading = false;
        mFooterView.setVisibility(GONE);
    }

    /*
	 * 定义加载更多接口
	 */
    public interface OnLoadListener {
        public void onLoad();
    }

    // 加载更多监听
    public void setOnLoadListener(OnLoadListener onLoadListener) {
        this.mLoadEnable = true;
        this.mOnLoadListener = onLoadListener;
    }
    
    @Override
    protected void layoutChildren() {
        try {
            super.layoutChildren();
        } catch (IllegalStateException e) {
            Log.e(TAG, "This is not realy dangerous problem");
        }
    }

}
